import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';

import {
  Form,
  Card,
  Button,
  Modal,
  Input,
  InputNumber,
  Divider,
  Popconfirm,
  Row,
  Col,
  Radio,
} from 'antd';

import PageHeaderLayout from '../../layouts/PageHeaderLayout';

import styles from './Client.less';
import StandardTable from '../../components/StandardTable';

const FormItem = Form.Item;

const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');

const CustomModal = Form.create({
  onValuesChange(props, changedFields) {
    const { onModalChange } = props;
    onModalChange(changedFields);
  },
  mapPropsToFields(props) {
    const { modalData } = props;
    if (modalData) {
      return {
        clientId: Form.createFormField({
          value: modalData.clientId,
        }),
        clientSecret: Form.createFormField({
          value: modalData.clientSecret,
        }),
        scope: Form.createFormField({
          value: modalData.scope,
        }),
        authorizedGrantTypes: Form.createFormField({
          value: modalData.authorizedGrantTypes,
        }),
        webServerRedirectUri: Form.createFormField({
          value: modalData.webServerRedirectUri,
        }),
        authorities: Form.createFormField({
          value: modalData.authorities,
        }),
        accessTokenValidity: Form.createFormField({
          value: modalData.accessTokenValidity,
        }),
        refreshTokenValidity: Form.createFormField({
          value: modalData.refreshTokenValidity,
        }),
        additionalInformation: Form.createFormField({
          value: modalData.additionalInformation,
        }),
        autoapprove: Form.createFormField({
          value: modalData.autoapprove,
        }),
        resourceIds: Form.createFormField({
          value: modalData.resourceIds,
        }),
      }
    }
  },
})(props => {
  const {
    modalTitle,
    modalWidth,
    modalVisible,
    form,
    handleCloseModal,
    handleOk,
    modalLoading,
  } = props;
  return (
    <Modal
      title={modalTitle}
      width={modalWidth}
      visible={modalVisible}
      onCancel={handleCloseModal}
      onOk={() => {
        form.validateFields((err) => {
          if (err) return;
          handleOk();
        });
      }}
    >
      <Card
        loading={modalLoading}
      >
        <Form layout="vertical">
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="编号">
                {form.getFieldDecorator('clientId', {
                  rules: [{max: 40, required: true, message: '长度在40个字符以内'}],
                })(<Input placeholder="请输入编号" />)}
              </FormItem>
            </Col>
            <Col xm={24} sm={12}>
              <FormItem label="密钥">
                {form.getFieldDecorator('clientSecret', {
                  rules: [{max: 256, required: true, message: '长度在256个字符以内'}],
                })(<Input placeholder="请输入密钥" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="域">
                {form.getFieldDecorator('scope', {
                  rules: [{max: 256, required: true, message: '长度在256个字符以内'}],
                })(<Input placeholder="请输入域" />)}
              </FormItem>
            </Col>
            <Col xm={24} sm={12}>
              <FormItem label="授权模式">
                {form.getFieldDecorator('authorizedGrantTypes', {
                  rules: [{max: 256, required: true, message: '长度在256个字符以内'}],
                })(<Input placeholder="请输入授权模式" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="回调地址">
                {form.getFieldDecorator('webServerRedirectUri', {
                  rules: [{max: 256, message: '长度在256个字符以内'}],
                })(<Input placeholder="请输入回调地址" />)}
              </FormItem>
            </Col>
            <Col xm={24} sm={12}>
              <FormItem label="权限">
                {form.getFieldDecorator('authorities', {
                  rules: [{max: 256, message: '长度在256个字符以内'}],
                })(<Input placeholder="请输入权限" />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="请求令牌">
                {form.getFieldDecorator('accessTokenValidity', {
                  rules: [{max: 99999999999, type: 'integer', message: '必须是数字且长度不能超过11位'}],
                })(<InputNumber placeholder="请输入请求令牌" style={{ width: '100%' }} />)}
              </FormItem>
            </Col>
            <Col xm={24} sm={12}>
              <FormItem label="刷新令牌">
                {form.getFieldDecorator('refreshTokenValidity', {
                  rules: [{max: 99999999999, type: 'integer', message: '必须是数字且长度不能超过11位'}],
                })(<InputNumber placeholder="请输入刷新令牌" style={{ width: '100%' }} />)}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xs={24} sm={12}>
              <FormItem label="扩展信息">
                {form.getFieldDecorator('additionalInformation', {
                  rules: [{max: 4096, message: '长度在4096个字符以内'}],
                })(<Input placeholder="请输入扩展信息" />)}
              </FormItem>
            </Col>
            <Col xs={24} sm={12}>
              <FormItem label="自动放行">
                {form.getFieldDecorator('autoapprove', {
                  rules: [{required: true, message: '请选择'}],
                })(
                  <Radio.Group>
                    <Radio value="true">是</Radio>
                    <Radio value="false">否</Radio>
                  </Radio.Group>
                )}
              </FormItem>
            </Col>
          </Row>
          <Row gutter={{xs: 12, sm: 24}}>
            <Col xm={24} sm={12}>
              <FormItem label="资源ID">
                {form.getFieldDecorator('resourceIds', {
                  rules: [{max: 256, message: '长度在256个字符以内'}],
                })(<Input placeholder="请输入资源ID" />)}
              </FormItem>
            </Col>
          </Row>
        </Form>
      </Card>
    </Modal>
  )
});

@connect(({ client, loading }) => ({
  client,
  loading: loading.effects['client/fetch'],
  modalLoading: loading.effects['client/operation'],
}))
@Form.create()
export default class Client extends PureComponent {
  state = {
    selectedRows:[],
    formValues: {},
  };

  componentDidMount() {
    window.addEventListener('resize', this.resize);
    const { dispatch } = this.props;
    dispatch({
      type: 'client/fetch',
      payload: {},
    });
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
  }

  resize = () => {
    const { dispatch, client: { selectedClient} } = this.props;
    dispatch({
      type: 'client/changeModalStatus',
      payload: {
        modal: {
          width: window.innerWidth / 2,
        },
        selectedClient,
      },
    });
  };

  handleOperateClient = (mode, clientId = '#') => {
    const { dispatch } = this.props;
    dispatch({
      type: 'client/operation',
      payload: {
        clientId,
        mode,
      },
    });
  };

  handleCloseModal = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'client/initModal',
    });
  };

  handleModalChange = changedFields => {
    const { dispatch } = this.props;
    dispatch({
      type: 'client/changeSelectedClient',
      payload: changedFields,
    });
  };

  handleStandardTableChange = (pagination, filtersArg, sorter) => {
    const { dispatch } = this.props;
    const {formValues} = this.state;

    const filters = Object.keys(filtersArg).reduce((obj, key) => {
      const newObj = {...obj};
      newObj[key] = getValue(filtersArg[key]);
      return newObj;
    }, {});

    const params = {
      page: pagination.current,
      limit: pagination.pageSize,
      ...formValues,
      ...filters,
    };

    if (sorter.field) {
      params.orderByField = `${sorter.field}`;
      params.isAsc = sorter.order === 'ascend';
    }

    dispatch({
      type: 'client/fetch',
      payload: params,
    });
  };

  handleSearch = e => {
    e.preventDefault();

    const { dispatch, form } = this.props;

    form.validateFields((err, fieldsValue) => {
      if (err) return;
      const values = {
        ...fieldsValue,
      };

      this.setState({
        formValues: values,
      });

      dispatch({
        type: 'client/fetch',
        payload: values,
      });
    });
  };

  handleFormReset = () => {
    const {form, dispatch} = this.props;
    form.resetFields();
    this.setState({
      formValues: {},
    });
    dispatch({
      type: 'client/fetch',
      payload: {},
    });
  };

  clientCrud = () => {
    const {
      dispatch,
      client: {
        selectedClient,
        modal: {
          mode,
        },
      },
    } = this.props;

    switch (mode) {
      case "Add":
        dispatch({
          type: 'client/add',
          payload: {
            clientId: selectedClient.clientId,
            clientSecret: selectedClient.clientSecret === undefined ? '' : selectedClient.clientSecret,
            scope: selectedClient.scope === undefined ? '' : selectedClient.scope,
            authorizedGrantTypes: selectedClient.authorizedGrantTypes === undefined ? '' : selectedClient.authorizedGrantTypes,
            webServerRedirectUri: selectedClient.webServerRedirectUri === undefined ? '' : selectedClient.webServerRedirectUri,
            authorities: selectedClient.authorities === undefined ? '' : selectedClient.authorities,
            accessTokenValidity: selectedClient.accessTokenValidity === undefined ? null : selectedClient.accessTokenValidity,
            refreshTokenValidity: selectedClient.refreshTokenValidity === undefined ? null : selectedClient.refreshTokenValidity,
            additionalInformation: selectedClient.additionalInformation === undefined ? '' : selectedClient.additionalInformation,
            autoapprove: selectedClient.autoapprove === undefined ? 'false' : selectedClient.autoapprove,
            resourceIds: selectedClient.resourceIds === undefined ? '' : selectedClient.resourceIds,
          },
        });
        break;
      case "Update":
        // do update client
        dispatch({
          type: 'client/upd',
          payload: {
            clientId: selectedClient.clientId,
            clientSecret: selectedClient.clientSecret === undefined ? '' : selectedClient.clientSecret,
            scope: selectedClient.scope === undefined ? '' : selectedClient.scope,
            authorizedGrantTypes: selectedClient.authorizedGrantTypes === undefined ? '' : selectedClient.authorizedGrantTypes,
            webServerRedirectUri: selectedClient.webServerRedirectUri === undefined ? '' : selectedClient.webServerRedirectUri,
            authorities: selectedClient.authorities === undefined ? '' : selectedClient.authorities,
            accessTokenValidity: selectedClient.accessTokenValidity === undefined ? null : selectedClient.accessTokenValidity,
            refreshTokenValidity: selectedClient.refreshTokenValidity === undefined ? null : selectedClient.refreshTokenValidity,
            additionalInformation: selectedClient.additionalInformation === undefined ? '' : selectedClient.additionalInformation,
            autoapprove: selectedClient.autoapprove === undefined ? 'false' : selectedClient.autoapprove,
            resourceIds: selectedClient.resourceIds === undefined ? '' : selectedClient.resourceIds,
          },
        });
        break;
      case "Delete":
        // do delete client
        break;
      default:
        break;
    }
  };

  render() {
    const {
      selectedRows,
    } = this.state;
    const {
      form,
      client: { data, selectedClient, modal: {width, visible, title} },
      loading,
      modalLoading,
    } = this.props;

    const columns = [
      {
        title: '编号',
        dataIndex: 'clientId',
      },
      {
        title: '密钥',
        dataIndex: 'clientSecret',
      },
      {
        title: '域',
        dataIndex: 'scope',
      },
      {
        title: '授权模式',
        dataIndex: 'authorizedGrantTypes',
      },
      {
        title: '回调地址',
        dataIndex: 'webServerRedirectUri',
      },
      {
        title: '权限',
        dataIndex: 'authorities',
      },
      {
        title: '请求令牌',
        dataIndex: 'accessTokenValidity',
      },
      {
        title: '刷新令牌',
        dataIndex: 'refreshTokenValidity',
      },
      {
        title: '扩展信息',
        dataIndex: 'additionalInformation',
      },
      {
        title: '自动放行',
        dataIndex: 'autoapprove',
        render: autoapprove => autoapprove === 'true' ? '是' : '否',
      },
      {
        title: '资源ID',
        dataIndex: 'resourceIds',
      },
      {
        title: '操作',
        render: (_, client) => (
          <Fragment>
            <a onClick={() => this.handleOperateClient("Update", client.clientId)}>编辑</a>
            <Divider type="vertical" />
            <Popconfirm title="确定删除?" onConfirm={() => this.handleOperateClient('Delete', client.clientId)} okText="删除" cancelText="取消">
              <a>删除</a>
            </Popconfirm>
          </Fragment>
        ),
      },
    ];

    return (
      <PageHeaderLayout title="路由管理">
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListOperator}>
              <Form onSubmit={this.handleSearch} layout="inline">
                <Row gutter={{md: 8, lg: 24, xl: 48}}>
                  <Col md={8} sm={24}>
                    <FormItem label="客户端编号">
                      {form.getFieldDecorator('client_id')(<Input placeholder="请输入" style={{ width: '100%' }} />)}
                    </FormItem>
                  </Col>
                  <Col md={8} sm={24}>
                    <span className={styles.submitButtons}>
                      <Button type="primary" htmlType="submit">
                        查询
                      </Button>
                      <Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
                        重置
                      </Button>
                    </span>
                  </Col>
                  <Col md={8} sm={24}>
                    <Button icon="plus" type="primary" onClick={() => this.handleOperateClient("Add")}>
                      新建
                    </Button>
                  </Col>
                </Row>
              </Form>
            </div>
            <StandardTable
              selectedRows={selectedRows}
              loading={loading}
              rowKey="clientId"
              data={data}
              columns={columns}
              onChange={this.handleStandardTableChange}
            />
          </div>
        </Card>
        <CustomModal
          modalTitle={title}
          modalWidth={width}
          modalVisible={visible}
          handleCloseModal={this.handleCloseModal}
          handleOk={this.clientCrud}
          modalLoading={modalLoading}
          modalData={selectedClient}
          onModalChange={this.handleModalChange}
        />
      </PageHeaderLayout>
    );
  }
}
